package com.ansion.commonchat.contact.systemcontact;

import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;

import com.ansion.log.VLog;
import com.ansion.string.StringUtils;
import com.ansion.utils.ResourceUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AndroidCotactsFactory_2_0 {

    private static final String TAG = "AndroidCotactsFactory_2_0";
    private static AndroidContactsObserver g_observer = null;

    public static HashMap<Integer, AndroidContactDB> getAllContacts() {

        HashMap<Integer, AndroidContactDB> dbContacts = new HashMap<Integer, AndroidContactDB>();

        /**
         * 大致从View_data中获取数据，Data表中每一行数据表示contact的某一条属性。
         * 根据Data.MIMETYPE的类型，Data.DATA1可能记录的是Phone.NUMBER,
         * Email.DATA,CommonDataKinds.StructuredName.DISPLAY_NAME.
         * 若果Data.MIMETYPE是5(phone_v2) Data.DATA2表示Phone.TYPE
         * 若果Data.MIMETYPE是10(photo) Data.DATA15表示CommonDataKinds.Photo.PHOTO
         */
        Cursor cur = ResourceUtils
                .getContext()
                .getContentResolver()
                .query(Data.CONTENT_URI,
                        new String[]{Data.DATA_VERSION, Data.CONTACT_ID, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA5, Data.PHOTO_ID, Data.RAW_CONTACT_ID, Data.LAST_TIME_CONTACTED, Data.TIMES_CONTACTED},
                        getQuerySelection(), null, null);

        if (cur == null)
            return dbContacts;

        int contactIdColumn = cur.getColumnIndex(Data.CONTACT_ID);
        int mimeColumn = cur.getColumnIndex(Data.MIMETYPE);
        int dataVersionColumn = cur.getColumnIndex(Data.DATA_VERSION);
        int data1Column = cur.getColumnIndex(Data.DATA1);
        int data2Column = cur.getColumnIndex(Data.DATA2);
        int data3Column = cur.getColumnIndex(Data.DATA3);
        int data5Column = cur.getColumnIndex(Data.DATA5);
        int photoIdColumn = cur.getColumnIndex(Data.PHOTO_ID);
        int rowContactIdColumn = cur.getColumnIndex(Data.RAW_CONTACT_ID);
        int lastTimeContactedColumn = cur.getColumnIndex(Data.LAST_TIME_CONTACTED);
        int timesContactedColumn = cur.getColumnIndex(Data.TIMES_CONTACTED);

        while (cur.moveToNext()) {

            try {
                String mime = cur.getString(mimeColumn);
                int contactId = cur.getInt(contactIdColumn);
                int photoId = cur.getInt(photoIdColumn);
                AndroidContactDB contact = dbContacts.get(contactId);
                if (contact == null) {
                    contact = new AndroidContactDB(contactId);
                    dbContacts.put(contactId, contact);
                }
                contact.setAvatarAvailable(photoId > 0);
                int dataVersion = cur.getInt(dataVersionColumn);
                if (VLog.OPEN_LOG)
                    VLog.i(TAG, "read DB data,version:%d,mime:%s contactId:%d,rawContactId:%d,data1:%s,data2:%s,data3:%s,data5:%s,timesContactedColumn:%d,lastTimeContactedColumn:%d", dataVersion, mime, contactId, cur.getInt(rowContactIdColumn),
                            cur.getString(data1Column), cur.getString(data2Column), cur.getString(data3Column), cur.getString(data5Column), cur.getInt(timesContactedColumn), cur.getLong(lastTimeContactedColumn));
                if (mime.equals(Phone.CONTENT_ITEM_TYPE)) {

                    String original = cur.getString(data1Column);
                    String phone = StringUtils.getNumberOfString(original);
                    int type = cur.getInt(data2Column);
                    int rowContactId = cur.getInt(rowContactIdColumn);
                    String label = cur.getString(data3Column);

                    int times = cur.getInt(timesContactedColumn);
                    long lastTime = cur.getLong(lastTimeContactedColumn);

                    AndroidContactPhoneBean phoneBean = new AndroidContactPhoneBean();
                    phoneBean.setPhone(phone);
                    phoneBean.setPhoneOriginal(original);
                    phoneBean.setPhoneType(type);
                    phoneBean.setRowContactId(rowContactId);
                    phoneBean.setLabel(label);
                    phoneBean.timesContacted = times;
                    phoneBean.last_timecontacted = lastTime;
                    contact.addPhoneBean(phoneBean);
                } else if (mime.equals(Email.CONTENT_ITEM_TYPE)) {

                    String address = cur.getString(data1Column);
                    int type = cur.getInt(data2Column);
                    String label = cur.getString(data3Column);

                    AndroidContactEmailBean email = new AndroidContactEmailBean(address, type, label);
                    contact.addEmail(email);

                } else if (mime.equals(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
                    //由于name会出现多个版本，所以需要比对数据版本
                    if (contact.getNameDataVersion() <= dataVersion) {
                        contact.setNameDataVersion(dataVersion);
                        contact.setName(cur.getString(data1Column));
                        contact.setFirstName(cur.getString(data2Column));
                        contact.setLastName(cur.getString(data3Column));
                        contact.setMiddleName(cur.getString(data5Column));
                    }


                }
            } catch (Exception e) {
                VLog.e(TAG, e);
            }
        }
        cur.close();
        if (g_observer == null) {
            g_observer = new AndroidContactsObserver();
            ResourceUtils.getContext().getContentResolver()
                    .registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, g_observer);
        }
        return dbContacts;
    }

    private static String querySelection = "";

    private static String getQuerySelection() {
        if (!TextUtils.isEmpty(querySelection)) {
            return querySelection;
        }
        StringBuffer sb = new StringBuffer();
        sb.append("( ");
        sb.append(Data.MIMETYPE);
        sb.append(" = '");
        sb.append(Phone.CONTENT_ITEM_TYPE);
        sb.append("'");

        sb.append(" or ");
        sb.append(Data.MIMETYPE);
        sb.append(" = '");
        sb.append(Email.CONTENT_ITEM_TYPE);
        sb.append("'");

        sb.append(" or ");
        sb.append(Data.MIMETYPE);
        sb.append(" = '");
        sb.append(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        sb.append("'");
        sb.append(")");


//        sb.append(" AND NOT (account_type NOT NULL AND ( account_type = '");
//        sb.append(SyncAdapterColumns.ACCOUNT_TYPE);
//
//        sb.append("' OR account_type = 'com.whatsapp'");
//        sb.append(" OR account_type = 'org.telegram.messenger'");
//        sb.append(" OR account_type = 'com.instanza.cocovoice'");
//        sb.append(") )");

//        sb.append(" or ");
//        sb.append(Data.MIMETYPE);
//        sb.append(" = '");
//        sb.append(CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
//        sb.append("'");

        querySelection = String.valueOf(sb);

        VLog.i(TAG, "querySelection--" + querySelection);

        return querySelection;

    }


    private static int g_hasPinyinField = -1;

    private static Cursor getCursorOrderByPinyin_2_0(ContentResolver cr) {
        Cursor persons_cur = null;
        String selection = "(" + ContactsContract.Contacts.DISPLAY_NAME + " is not null) and ("
                + ContactsContract.Contacts.HAS_PHONE_NUMBER + "= 1)";
        final String[] CONTACTS_PROJECTION_1 = new String[]{ContactsContract.Contacts._ID,
                ContactsContract.Contacts.SORT_KEY_PRIMARY};
        if (g_hasPinyinField == -1 || g_hasPinyinField == 1) {
            try {
                persons_cur = cr.query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_PROJECTION_1, selection, null,
                        "sort_key COLLATE LOCALIZED asc");
                g_hasPinyinField = 1;
                return persons_cur;
            } catch (Exception e) {
                VLog.e(TAG, e);
            }
        }

        g_hasPinyinField = 0;
        final String[] CONTACTS_PROJECTION_2 = new String[]{ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME};
        try {
            persons_cur = cr.query(ContactsContract.Contacts.CONTENT_URI, CONTACTS_PROJECTION_2, selection, null,
                    ContactsContract.Contacts.DISPLAY_NAME + "  COLLATE LOCALIZED asc");
            return persons_cur;
        } catch (Exception e) {
            VLog.e(TAG, e);
        }

        return persons_cur;
    }

    public static void getSortedIds(List<Integer> ids, Map<Integer, AndroidContactDB> contacts) {
        Cursor cursor = getCursorOrderByPinyin_2_0(ResourceUtils.getContext().getContentResolver());
        if (cursor == null)
            return;
        // Set<Integer> idSet = new HashSet<Integer>();
        try {
            if (cursor.getCount() > 0) {

                cursor.moveToFirst();
                do {
                    int id = cursor.getInt(0);
                    // if(idSet.contains(id))
                    // continue;

                    // idSet.add(id);
                    String sortKey = cursor.getString(1);
                    ids.add(id);
                    AndroidContactDB contact = contacts.get(id);
                    if (contact == null)
                        continue;
                    contact.setSortKey(sortKey);

                } while (cursor.moveToNext());
            }
        } catch (Exception e) {
            VLog.e(TAG, e);
        } finally {
            cursor.close();
        }

    }

    public static void unRegisterContactsContentObserver() {
        if (g_observer != null) {
            ResourceUtils.getContext().getContentResolver().unregisterContentObserver(g_observer);
            g_observer = null;
        }
    }
}
